﻿using SC2BuildPlannerLib.Enums;
using System;

namespace SC2BuildPlannerLib.Resources
{
    /// <summary>
    /// Class for supply data
    /// </summary>
    public class Supply : Resource
    {
        /// <summary>
        /// Property for the initial supply maximum
        /// </summary>
        private int _initialMaximum;
        public int InitialMaximum
        {
            get { return _initialMaximum; }
            set { _initialMaximum = value; }
        }
        
        /// <summary>
        /// Property for supply under construction
        /// </summary>
        private int _pendingSupply;
        public int PendingSupply
        {
            get { return _pendingSupply; }
            set { _pendingSupply = value; }
        }

        /// <summary>
        /// Read-only property for the maximum supply, including under construction
        /// </summary>
        public int PendingMaximum
        {
            get { return Math.Min(200, Maximum.Value + PendingSupply); }
        }

        /// <summary>
        /// Read-only property for the actual maximum supply
        /// </summary>
        public int ActualMaximum
        {
            get { return Math.Min(200, Maximum.Value); }
        }

        /// <summary>
        /// Read-only property for the visible supply used
        /// </summary>
        public int DisplayedAmount
        {
            get { return (int)Math.Ceiling(Amount); }
        }

        /// <summary>
        /// Override Amount field and property to be double type
        /// </summary>
        private override double _amount;
        public override double Amount
        {
            get { return _amount; }
            set { _amount = value; }
        }

        /// <summary>
        /// Constructor with parameter for the race being simulated
        /// </summary>
        /// <param name="race">Race being simulated</param>
        public Supply(Race race)
        {
            InitialAmount = 6;
            InitialMaximum = race == Race.Terran ? 11 : 10;
            Reset();
        }

        /// <summary>
        /// Method for determining if supply will be available in the future for this supply change
        /// </summary>
        /// <param name="delta">Delta amount</param>
        /// <returns></returns>
        public bool CanPendingChange(int delta)
        {
            return Amount + delta <= PendingMaximum && base.CanChange(delta);
        }

        /// <summary>
        /// Method for changing the supply maximum under construction
        /// </summary>
        /// <param name="delta">Delta maximum under construction</param>
        public void ChangePendingSupply(int delta)
        {
            PendingSupply += delta;
        }

        /// <summary>
        /// Method for changing the supply maximum
        /// </summary>
        /// <param name="delta">Delta maximum</param>
        public void ChangeMaximum(int delta)
        {
            Maximum += delta;
            if (delta > 0)
                PendingSupply -= delta;
        }

        /// <summary>
        /// Override CanChange method to respect maximum
        /// </summary>
        /// <param name="delta">Delta amount</param>
        /// <returns></returns>
        public override bool CanChange(int delta)
        {
            return Amount + delta <= ActualMaximum && base.CanChange(delta);
        }

        /// <summary>
        /// Override Change method to allow the resource to increase over maximum (e.g. Zerg building cancels)
        /// </summary>
        /// <param name="delta">Delta amount</param>
        public override void Change(int delta)
        {
            Amount += delta;
        }

        public override void Reset()
        {
            base.Reset();
            Maximum = InitialMaximum;
            PendingSupply = 0;
        }
    }
}
